package com.baitiaojun.log.core.utils;


import com.baitiaojun.common.constants.Constants;
import com.baitiaojun.common.utils.date.DateTimeUtils;
import com.baitiaojun.common.utils.exception.ExceptionUtils;
import com.baitiaojun.common.utils.ip.IpUtils;
import com.baitiaojun.common.utils.servlet.ServletUtils;
import com.baitiaojun.common.utils.spring.SpringUtils;
import com.baitiaojun.common.utils.string.StringUtils;
import com.baitiaojun.datasource.core.datasource.DataSourceHolder;
import com.baitiaojun.log.core.dto.SysLoginDTO;
import com.baitiaojun.log.core.dto.SysOperationLogDTO;
import com.baitiaojun.log.core.service.OperationLogService;
import com.baitiaojun.log.core.service.SysLoginService;
import eu.bitwalker.useragentutils.UserAgent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.TimerTask;

public class LogUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(LogUtils.class);

    /**
     * 登陆日志添加,tenant为空就使用默认数据源添加日志, 都则用指定租户的数据源
     * @param username
     * @param status
     * @param message
     * @param args
     * @return
     */
    public static TimerTask recordLoginLog(final String username, final String status, final String message, final Object... args) {
        return recordLoginLog(null, username, status, message, args);
    }

    /**
     * 登陆、注册、登出访问日志
     * @param tenant
     * @param username
     * @param status
     * @param message
     * @param args
     * @return
     */
    public static TimerTask recordLoginLog(String tenant, final String username, final String status, final String message, final Object... args) {
        HttpServletRequest request = ServletUtils.getRequest();
        UserAgent userAgent =UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        String ip = IpUtils.getIp(request);
        String address = IpUtils.getAddressInfo(ip);
        return new TimerTask() {
            @Override
            public void run() {
                try {
                    recordLoginLog(tenant, username, status, message, ip, address, userAgent, args);
                } catch (Exception e) {
                    LOGGER.warn(ExceptionUtils.getExpMsg(e));
                }
            }
        };
    }

    /**
     * 登陆、注册、登出访问日志
     * @param tenant
     * @param username
     * @param status
     * @param message
     * @param ip
     * @param address
     * @param userAgent
     * @param args
     */
    public static void recordLoginLog(String tenant, final String username,
                                  final String status, final String message, String ip,
                                 String address, UserAgent userAgent, final Object... args) {
        String msg = format(ip) + format(username) + format(status) + format(message);
        LOGGER.info(msg, args);
        String browser = userAgent.getBrowser().getName();
        SysLoginDTO sysLoginDTO = new SysLoginDTO();
        sysLoginDTO.setIpaddr(ip);
        sysLoginDTO.setLoginLocation(address);
        sysLoginDTO.setLoginTime(DateTimeUtils.parseDate(DateTimeUtils.getDateTime()));
        sysLoginDTO.setBrowser(browser);
        sysLoginDTO.setOS(userAgent.getOperatingSystem().getName());
        sysLoginDTO.setUserName(username);
        if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.REGISTER, Constants.LOGOUT)) {
            sysLoginDTO.setStatus(Constants.SUCCESS);
        } else {
            sysLoginDTO.setStatus(Constants.FAIL);
        }
        sysLoginDTO.setMsg(msg);
        //切换数据源
        if (StringUtils.isNotEmpty(tenant)) {
            DataSourceHolder.setDb(tenant);
        }
        SysLoginService sysLoginService = SpringUtils.getBean(SysLoginService.class);
        if (sysLoginService != null) {
            LOGGER.info("=================调用[SysLoginServiceImpl.addSysLoginLog]进行登陆日志落库=================");
            sysLoginService.addSysLoginLog(sysLoginDTO);
        }
    }

    /**
     * 手动添加业务操作日志
     * @param tenant
     * @return
     */
    public static TimerTask recordRepoLog(String tenant, SysOperationLogDTO sysOperLogDTO) {
        if (StringUtils.isNotEmpty(tenant)) {
            DataSourceHolder.setDb(tenant);
        }
        OperationLogService sysLogService = SpringUtils.getBean(OperationLogService.class);
        return new TimerTask() {
            @Override
            public void run() {
                LOGGER.info("=================调用[SysLogServiceImpl.addLog]进行操作日志落库=================");
                try {
                    sysLogService.addLog(sysOperLogDTO);
                } catch (Exception e) {
                    LOGGER.warn(ExceptionUtils.getExpMsg(e));
                }
            }
        };
    }

    /**
     * 格式化日志输出
     * @param msg
     * @return
     */
    public static String format(Object msg) {
        if (msg == null) {
            msg = "";
        }
        return "[" + msg + "]";
    }
}
